#include <functional>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <vector>
#include<iostream>
class H2O {
public:
    H2O() : h_count(0), o_count(0) {}

    void hydrogen(std::function<void()> releaseHydrogen) {
        std::unique_lock<std::mutex> lock(mtx);
        // 等待直到有足够的氢原子和氧原子可以组合成一个水分子
        cv.wait(lock, [this]{ return h_count < 2; });
        // 释放氢原子
        releaseHydrogen();
        h_count++;
        // 如果有两个氢原子和一个氧原子，重置计数器并通知所有等待的线程
        if (h_count == 2 && o_count == 1) {
            h_count = 0;
            o_count = 0;
            cv.notify_all();
        }
    }

    void oxygen(std::function<void()> releaseOxygen) {
        std::unique_lock<std::mutex> lock(mtx);
        // 等待直到有足够的氢原子和氧原子可以组合成一个水分子
        cv.wait(lock, [this]{ return o_count < 1; });
        // 释放氧原子
        releaseOxygen();
        o_count++;
        // 如果有两个氢原子和一个氧原子，重置计数器并通知所有等待的线程
        if (h_count == 2 && o_count == 1) {
            h_count = 0;
            o_count = 0;
            cv.notify_all();
        }
    }

private:
    std::mutex mtx;  // 互斥锁
    std::condition_variable cv;  // 条件变量
    int h_count;  // 氢原子计数器
    int o_count;  // 氧原子计数器
};


int main() {
    H2O h2o;
    std::vector<std::thread> threads;

    // 创建多个氢线程和氧线程
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(&H2O::hydrogen, &h2o, []{ std::cout << "H"; });
        threads.emplace_back(&H2O::hydrogen, &h2o, []{ std::cout << "H"; });
        threads.emplace_back(&H2O::oxygen, &h2o, []{ std::cout << "O"; });
    }

    // 等待所有线程结束
    for (auto& t : threads) {
        t.join();
    }

    return 0;
}